package org.lql.chaos.mq.rabbitmq.config;

import org.lql.chaos.mq.rabbitmq.constant.RabbitMQConstant;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.ExchangeBuilder;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * @author: liangqinglong
 * @date: 2025-08-09 13:36
 * @description:
 **/
@Configuration
public class MultiExchangeConfig {

	@Bean(RabbitMQConstant.FANOUT_EXCHANGE)
	public FanoutExchange fanoutExchange() {
		return ExchangeBuilder.fanoutExchange(RabbitMQConstant.FANOUT_EXCHANGE)
				.durable(true) // 是否持久化，默认true
				.build();
	}

	@Bean(RabbitMQConstant.FANOUT_QUEUE_1)
	public Queue fanoutQueue1() {
		return new Queue(RabbitMQConstant.FANOUT_QUEUE_1);
	}

	@Bean(RabbitMQConstant.FANOUT_QUEUE_2)
	public Queue fanoutQueue2() {
		return new Queue(RabbitMQConstant.FANOUT_QUEUE_2);
	}

	@Bean
	public Binding bindingFanout1(
			@Qualifier(RabbitMQConstant.FANOUT_EXCHANGE) FanoutExchange exchange,
			@Qualifier(RabbitMQConstant.FANOUT_QUEUE_1) Queue queue) {
		return BindingBuilder.bind(queue).to(exchange);
	}

	@Bean
	public Binding bindingFanout2(
			@Qualifier(RabbitMQConstant.FANOUT_EXCHANGE) FanoutExchange exchange,
			@Qualifier(RabbitMQConstant.FANOUT_QUEUE_2) Queue queue) {
		return BindingBuilder.bind(queue).to(exchange);
	}

	// ===================================================================================================================

	@Bean(RabbitMQConstant.DIRECT_EXCHANGE)
	public DirectExchange directExchange() {
		return ExchangeBuilder.directExchange(RabbitMQConstant.DIRECT_EXCHANGE)
				.durable(true) // 是否持久化，默认true
				.build();
	}

	@Bean(RabbitMQConstant.DIRECT_QUEUE)
	public Queue directQueue() {
		return new Queue(RabbitMQConstant.DIRECT_QUEUE);
	}

	@Bean
	public Binding bindingDirect(
			@Qualifier(RabbitMQConstant.DIRECT_EXCHANGE) DirectExchange exchange,
			@Qualifier(RabbitMQConstant.DIRECT_QUEUE) Queue queue
	) {
		// 路由键为 "direct.routing.key"
		return BindingBuilder.bind(queue).to(exchange).with(RabbitMQConstant.DIRECT_ROUTING_KEY);
	}

	// ===================================================================================================================

	@Bean(RabbitMQConstant.TOPIC_EXCHANGE)
	public TopicExchange topicExchange() {
		return ExchangeBuilder.topicExchange(RabbitMQConstant.TOPIC_EXCHANGE)
				.durable(true) // 是否持久化，默认true
				.build();
	}

	@Bean(RabbitMQConstant.TOPIC_QUEUE_1)
	public Queue topicQueue1() {
		return new Queue(RabbitMQConstant.TOPIC_QUEUE_1);
	}

	@Bean(RabbitMQConstant.TOPIC_QUEUE_2)
	public Queue topicQueue2() {
		return new Queue(RabbitMQConstant.TOPIC_QUEUE_2);
	}

	@Bean
	public Binding bindingTopic1(
			@Qualifier(RabbitMQConstant.TOPIC_EXCHANGE) TopicExchange exchange,
			@Qualifier(RabbitMQConstant.TOPIC_QUEUE_1) Queue queue
	) {
		// 路由键为 "*.rabbitmq.*"
		return BindingBuilder.bind(queue).to(exchange).with(RabbitMQConstant.TOPIC_X_RABBITMQ_X_KEY);
	}

	@Bean
	public Binding bindingTopic2(
			@Qualifier(RabbitMQConstant.TOPIC_EXCHANGE) TopicExchange exchange,
			@Qualifier(RabbitMQConstant.TOPIC_QUEUE_2) Queue queue
	) {
		// 路由键模糊匹配 "*.*.client"
		return BindingBuilder.bind(queue).to(exchange).with(RabbitMQConstant.TOPIC_X_X_CLIENT_KEY);
	}

	@Bean
	public Binding bindingTopic3(
			@Qualifier(RabbitMQConstant.TOPIC_EXCHANGE) TopicExchange exchange,
			@Qualifier(RabbitMQConstant.TOPIC_QUEUE_2) Queue queue
	) {
		// 路由键模糊匹配 "com.#"
		return BindingBuilder.bind(queue).to(exchange).with(RabbitMQConstant.TOPIC_COM_X_KEY);
	}

	// ===================================================================================================================

	@Bean(RabbitMQConstant.PERSISTENT_EXCHANGE)
	public DirectExchange persistentExchange() {
		return ExchangeBuilder.directExchange(RabbitMQConstant.PERSISTENT_EXCHANGE)
				.durable(true) // 是否持久化，默认true
				.build();
	}

	@Bean(RabbitMQConstant.PERSISTENT_QUEUE)
	public Queue persistentQueue() {
		return new Queue(RabbitMQConstant.PERSISTENT_QUEUE);
	}

	@Bean
	public Binding bindingPersistent(
			@Qualifier(RabbitMQConstant.PERSISTENT_EXCHANGE) DirectExchange exchange,
			@Qualifier(RabbitMQConstant.PERSISTENT_QUEUE) Queue queue
	) {
		// 路由键为 "persistent.routing.key"
		return BindingBuilder.bind(queue).to(exchange).with(RabbitMQConstant.PERSISTENT_ROUTING_KEY);
	}

	// ===================================================================================================================

	@Bean(RabbitMQConstant.DEFAULT_EXCHANGE)
	public DirectExchange defaultExchange() {
		Map<String, Object> args = new HashMap<>();
		// 设置备用交换机参数
		args.put("alternate-exchange", RabbitMQConstant.ALTERNATE_EXCHANGE);
		return ExchangeBuilder.directExchange(RabbitMQConstant.DEFAULT_EXCHANGE)
				.durable(true) // 是否持久化，默认true
				.withArguments(args) // 设置备用交换机参数
				.build();
	}

	@Bean(RabbitMQConstant.ALTERNATE_EXCHANGE)
	public DirectExchange alternateExchange() {
		return ExchangeBuilder.directExchange(RabbitMQConstant.ALTERNATE_EXCHANGE)
				.durable(true) // 是否持久化，默认true
				.build();
	}

	@Bean(RabbitMQConstant.ALTERNATE_QUEUE)
	public Queue alternateQueue() {
		return new Queue(RabbitMQConstant.ALTERNATE_QUEUE);
	}

	@Bean
	public Binding bindingAlternate(
			@Qualifier(RabbitMQConstant.ALTERNATE_EXCHANGE) DirectExchange exchange,
			@Qualifier(RabbitMQConstant.ALTERNATE_QUEUE) Queue queue
	) {
		// 路由键为 "alternate.routing.key"
		return BindingBuilder.bind(queue).to(exchange).with(RabbitMQConstant.ALTERNATE_ROUTING_KEY);
	}
}
